package com.bec.serialportlibrary;

import android.app.Activity;
import android.content.Context;
import android.os.CountDownTimer;
import android.util.Log;

import com.bec.serialportlibrary.devicetype.BaseDevice;
import com.bec.serialportlibrary.devicetype.DaHuaElectronicScale;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android_serialport_api.SerialPort;

/**
 * Created by lzp on 2018/5/23 0023.
 * 串口电子秤控制器
 */
public class SerialPortControllerImpl<T extends BaseDevice> implements SerialPortController {

    private static final String TAG = "SerialPortController";

    private T t;

    private String path;

    private int baudRate;

    private Context context;

    private boolean threadRunning;

    private SerialPort serialPort;

    private InputStream inputStream;

    private OutputStream outputStream;

    private OnDataReceivedListener onDataReceivedListener;

    private ReadThread readThread;

    //串口连接超时时间(单位：秒)
    private long timeOutLimit = 5L;

    private CountDownTimer countDownTimer;

    /**
     * @param context 上下文
     * @param t       串口秤类型
     */
    public SerialPortControllerImpl(Context context, T t) {
        this.context = context;
        this.t = t;
        path = t.getPath();
        baudRate = t.getBaudRate();
    }

    @Override
    public void openSerialPortAndReadData() throws RuntimeException {

        if (!(t instanceof DaHuaElectronicScale)) {
            throw new RuntimeException("设备不支持");
        }

        if (serialPort == null) {

            File device = new File(path);

            if (device.exists()) {

                try {
                    serialPort = new SerialPort(device, baudRate, 0);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                inputStream = serialPort.getInputStream();
                outputStream = serialPort.getOutputStream();

                Log.i(TAG, "OpenSerialPort: 打开串口成功");

                threadRunning = true;
                readThread = new ReadThread();
                readThread.start();

                if (countDownTimer == null) {
                    countDownTimer = new CountDownTimer(timeOutLimit * 1000, 1000) {
                        @Override
                        public void onTick(long millisUntilFinished) {
                            Log.i(TAG, "尝试连接：" + millisUntilFinished / 1000 + "秒");
                        }

                        @Override
                        public void onFinish() {
                            if (context != null && context instanceof Activity) {
                                ((Activity) context).runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        onDataReceivedListener.onDataReceived(false, null, 0);
                                        closeSerialPort();
                                    }
                                });
                            } else {
                                onDataReceivedListener.onDataReceived(false, null, 0);
                                closeSerialPort();
                            }
                        }
                    };
                }

                countDownTimer.start();
            } else {
                closeSerialPort();
                Log.i(TAG, "OpenSerialPort: 打开串口失败");
                throw new RuntimeException("端口不存在");
            }
        }
    }

    @Override
    public void closeSerialPort() {

        if (serialPort == null) {
            return;
        }

        if (countDownTimer != null) {
            countDownTimer.cancel();
        }

        try {

            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }

        } catch (IOException e) {
            Log.i(TAG, "CloseSerialPort: 输入输出流关闭异常");
            e.printStackTrace();
            return;
        } finally {
            threadRunning = false;
            if (serialPort != null) {
                serialPort.close();
                serialPort = null;
            }
            readThread = null;
        }

        Log.i(TAG, "CloseSerialPort: 关闭串口成功");
    }

    /**
     * @param data 需要发送的数据
     */
    @Override
    public void sendSerialPortCommand(byte[] data) {
        // TODO: 2018/6/14 0014 发送消息 暂无需求
    }

    @Override
    public SerialPortController setTimeOutLimit(long time) {
        this.timeOutLimit = time;
        return this;
    }

    @Override
    public void destroy() {

        if (countDownTimer != null) {
            countDownTimer.cancel();
            countDownTimer = null;
        }

        try {

            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }

        } catch (IOException e) {
            Log.i(TAG, "CloseSerialPort: 输入输出流关闭异常");
            e.printStackTrace();
            return;
        } finally {
            threadRunning = false;
            if (serialPort != null) {
                serialPort.close();
                serialPort = null;
            }
            inputStream = null;
            outputStream = null;
            readThread = null;
        }

        Log.i(TAG, "CloseSerialPort: 关闭串口成功");
    }

    @Override
    public SerialPortController setOnDataReceivedListener(OnDataReceivedListener onDataReceivedListener) {
        this.onDataReceivedListener = onDataReceivedListener;
        return this;
    }

    private class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();

            while (context != null && threadRunning) {

                byte[] buffer = new byte[32];

                int size;

                try {
                    size = inputStream.read(buffer);

                    if (size > 0) {

                        int i;

                        for (i = 0; i < buffer.length; i++) {

                            if (buffer[i] == 0x1 && i + 1 < buffer.length && buffer[i + 1] == 0x2 && i + 16 < buffer.length && buffer[i + 13] == 0x3 && buffer[i + 14] == 0x4) {

                                final byte[] response = new byte[16];

                                System.arraycopy(buffer, i, response, 0, response.length);

                                if (context != null && context instanceof Activity) {

                                    ((Activity) context).runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            onDataReceivedListener.onDataReceived(true, response, response.length);
                                            closeSerialPort();
                                        }
                                    });
                                } else {
                                    onDataReceivedListener.onDataReceived(true, response, response.length);
                                    closeSerialPort();
                                }
                            }
                        }

                    } else {
                        Log.i(TAG, "ReadThread:接收到数据大小：0");
                    }

                    Thread.sleep(50);

                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i(TAG, "ReadThread:数据读取异常");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Log.i(TAG, "ReadThread:睡眠异常");
                }
            }
        }
    }
}
